//
// Created by LiuYou on 2021/10/27.
//

#include <cstdio>
#include <cstdlib>


#define MAX_SIZE    120


static FILE* fp;


static ssize_t mygetline(char** lineptr, size_t* n, FILE* stream) {
    ssize_t count = 0;
    int buf;

    if (*lineptr == nullptr) {
        *n = MAX_SIZE;
        *lineptr = static_cast<char*>(malloc( *n ));
    }

    // 判断是否结束
    if ((buf = fgetc( stream )) == EOF) {
        return -1;
    }

    while ((buf = fgetc( stream )) != EOF) {
        if (buf == '\n') {
            count += 1;
            break;
        }

        count++;

        *(*lineptr + count - 1) = buf;
        *(*lineptr + count) = '\0';

        // 重新申请内存
        if (*n <= count)
            *lineptr = static_cast<char*>(realloc( *lineptr, count * 2 ));
    }

    return count;
}

/*
 * 这是一个错误的实现。但是给了我参考的意义 ——> 进行 EOF 的判断, 之前写的程序中没有一个是使用 EOF 的。
 * 写程序要头脑保持清醒, 考虑所有的条件。一步一步来, 别灰心。
 */
int main(int argc, char* argv[]) {
    if (argc < 2) {
        fprintf( stderr, "用法: %s filename", argv[0] );
        return 1;
    }


    fp = fopen( argv[1], "r" );
    if (fp == nullptr) {
        perror( "fopen()" );
        return 1;
    }
    atexit( [] {
        fclose( fp );
    } );

    char* linebuf = nullptr;
    size_t linesize = 0;

    while (true) {
        ssize_t readBytes = mygetline( &linebuf, &linesize, fp );
        if (readBytes < 0) {
            break;
        }
        printf( "%zd\n", readBytes );
        printf( "%s\n", linebuf );
    }


    if (linebuf) {
        free( linebuf );
    }


    return 0;
}
